/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package co.com.claro.administracionSolicitudes.beans;

import co.com.claro.administracionSolicitudes.dao.exceptions.ClaroException;
import co.com.claro.administracionSolicitudes.datamodel.SolicitudesDynamicDataModel;
import co.com.claro.administracionSolicitudes.db.EJBDatabaseSolicitudesLocal;
import co.com.claro.administracionSolicitudes.dto.SolicitudDto;
import co.com.claro.administracionSolicitudes.ejb.EJBAdminSolicitudesLocal;
import co.com.claro.administracionSolicitudes.entity.EstadosSolicitud;
import co.com.claro.administracionSolicitudes.entity.Grupo;
import co.com.claro.administracionSolicitudes.entity.Solicitud;
import co.com.claro.administracionSolicitudes.entity.Usuario;
import co.com.claro.administracionSolicitudes.entity.enums.EstadosSolicitudEnum;
import co.com.claro.administracionSolicitudes.entity.enums.GruposEnum;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;

/**
 *
 * @author Mike
 */
@ManagedBean
@ViewScoped
public class InicioBean {

    @EJB
    private EJBDatabaseSolicitudesLocal localDatabase;
    @EJB
    private EJBAdminSolicitudesLocal localAdminSol;
    @ManagedProperty(value = "#{usuarioSessionBean}")
    private UsuarioSessionBean sesionBean;
    /**
     * Rol al que pertenece el usuario loggeado al sistema
     */
    private Grupo rol;
    /**
     * Lista con las solicitudes hechas
     */
//    private List<Solicitud> solicitudes;
    private SolicitudesDynamicDataModel solicitudes;
    /**
     * Gerencia seleccionada por el usuario
     */
    private String gerenciaSeleccionado;
    /**
     * Lista con las solicitudes por aprobar
     */
//    private List<Solicitud> solicitudesAprobar;
    private SolicitudesDynamicDataModel solicitudesAprobar;
    /**
     * Variable que mustra la tabla para el aprobador
     */
    private boolean isAprobador;
    /**
     * Variable que mustra la tabla para el asignador
     */
    private boolean isAsignador;
    /**
     * Variable que mustra la tabla para el ejecutor
     */
    private boolean isEjecutor;

    private int filas = 30;

    private static final String COL_DEFAULT_SORT = "idSolicitud";

    private String columnaSorteada;
    private boolean ascendiente;

    public InicioBean() {
    }

    @PostConstruct
    public void inicializarValores() {
        rol = sesionBean.obtenerRolUsuario();

        ascendiente = true;
        columnaSorteada = COL_DEFAULT_SORT;

        llenarSolicitudes();
        llenarSolicitudesAprobar();
        cargarControles();
    }

    //++++++++++++++++++++++++++++++ MÉTODOS PROPIOS DEL BEAN ++++++++++++++++++++
    /**
     * Método que llena las solicitudes a mostrar en pantalla
     */
    private void llenarSolicitudes() {
        Usuario usuario = sesionBean.getUsuario();
        List<EstadosSolicitudEnum> estados = new ArrayList<EstadosSolicitudEnum>();

        estados.add(EstadosSolicitudEnum.CANCELADO);
        estados.add(EstadosSolicitudEnum.POR_APROBAR);
        estados.add(EstadosSolicitudEnum.POR_ASIGNAR);
        estados.add(EstadosSolicitudEnum.POR_EJECUTAR);

        SolicitudDto dto = new SolicitudDto();

        dto.setIdSolicitante(usuario.getIdUsuario());
        dto.setEstados(estados);
        dto.setAscendiente(ascendiente);
        dto.setCampoSorteado(columnaSorteada);

        solicitudes = new SolicitudesDynamicDataModel(localDatabase, dto);
    }

    private void llenarSolicitudesAprobar() {
        SolicitudDto dto = getDtoSolicitudesAprobar();

        solicitudesAprobar = new SolicitudesDynamicDataModel(localDatabase, dto);
    }

    /**
     * Método que obtiene el id del objeto contenido dentro del data table y
     * retorna la solicitude de la lista según el rol del usuario
     *
     * @param ActionEvent, evento para buscar el objeto dentro del contexto
     * @return Object, con el id del objeto
     */
    private Solicitud obtenerObjeto(ActionEvent event, String idComponente) {
        FacesContext context = FacesContext.getCurrentInstance();
        UIComponent componente = event.getComponent().findComponent(idComponente);
        Long id = (Long) componente.getValueExpression("value").getValue(context.getELContext());

        if (isAprobador) {
            return localDatabase.findSolicitudById(id);
        }
        return null;
    }

    /**
     * Método que permite saber que controles se deben mostrar y que valores
     * debe cargar cada control dependiendo del rol al que pertenezca el usuario
     */
    private void cargarControles() {
        if (GruposEnum.APROBADOR.getId() == rol.getIdGrupo()) {
            isAprobador = true;
        } else if (GruposEnum.ASIGNADOR.getId() == rol.getIdGrupo()) {
            isAsignador = true;
        } else if (GruposEnum.EJECUTOR.getId() == rol.getIdGrupo()) {
            isEjecutor = true;
        } else if (GruposEnum.ADMINISTRADOR.getId() == rol.getIdGrupo()) {
            isAprobador = true;
            isAsignador = true;
            isEjecutor = true;
        }
    }

//++++++++++++++++++++++++++++ EVENTOS PROPIOS DEL BEAN +++++++++++++++++++++++
    /**
     * Método que envía la solicitud para su aprobación
     *
     * @param event, el control que lanzó la acción y contiene los datos de la
     * solicitud que se envía para aprobación
     */
    public void aprobarSolicitud(ActionEvent event) {
        Solicitud solicitudAprobar = obtenerObjeto(event, "idSolicitudOutputText");
        solicitudAprobar.setUsuario(sesionBean.getUsuario().getUsername());
        solicitudAprobar.setEstado(new EstadosSolicitud(EstadosSolicitudEnum.POR_ASIGNAR.getId()));

        try {
            localAdminSol.aprobarSolicitud(solicitudAprobar);

        } catch (ClaroException ex) {
            Logger.getLogger(InicioBean.class
                    .getName()).log(Level.SEVERE, null, ex);
        }
        llenarSolicitudes();
        llenarSolicitudesAprobar();
    }

    /**
     * Método que envía la solicitud para su cancelación
     *
     * @param event, el control que lanzó la acción y contiene los datos de la
     * solicitud que se envía para cancelación
     */
    public void cancelarSolicitud(ActionEvent event) {
        Solicitud solicitudAprobar = obtenerObjeto(event, "idSolicitudOutputText");
        solicitudAprobar.setUsuario(sesionBean.getUsuario().getUsername());
        solicitudAprobar.setEstado(new EstadosSolicitud(EstadosSolicitudEnum.CANCELADO.getId()));

        try {
            localAdminSol.cancelarSolicitud(solicitudAprobar);

        } catch (ClaroException ex) {
            Logger.getLogger(InicioBean.class
                    .getName()).log(Level.SEVERE, null, ex);
        }
        llenarSolicitudes();
        llenarSolicitudesAprobar();
    }

    public void aprobarTodasSolicitudes() {
        try {
            SolicitudDto dto = getDtoSolicitudesAprobar();
            List<Solicitud> porAprobar = localDatabase.findSolicitudes(dto);

            for (Solicitud sol : porAprobar) {
                sol.setUsuario(sesionBean.getUsuario().getUsername());
                sol.setEstado(new EstadosSolicitud(EstadosSolicitudEnum.POR_ASIGNAR.getId()));
            }

            localAdminSol.aprobarSolicitudesMasivas(porAprobar);
        } catch (ClaroException ex) {
            Logger.getLogger(InicioBean.class.getName()).log(Level.SEVERE, null, ex);
        }
        llenarSolicitudes();
        llenarSolicitudesAprobar();
    }

    public void cancelarTodasSolicitudes() {
        try {
            SolicitudDto dto = getDtoSolicitudesAprobar();
            List<Solicitud> porCancelar = localDatabase.findSolicitudes(dto);

            for (Solicitud sol : porCancelar) {
                sol.setEstado(new EstadosSolicitud(EstadosSolicitudEnum.CANCELADO.getId()));
                sol.setUsuario(sesionBean.getUsuario().getUsername());
            }

            localAdminSol.cancelarSolicitudesMasivas(porCancelar);
        } catch (ClaroException ex) {
            Logger.getLogger(InicioBean.class.getName()).log(Level.SEVERE, null, ex);
        }
        llenarSolicitudes();
        llenarSolicitudesAprobar();
    }

    public boolean paginado() {
        return solicitudes.getTotalCount() > filas;
    }

    public boolean paginadoAprobaciones() {
        if (solicitudesAprobar != null) {
            return solicitudesAprobar.getTotalCount() > filas;
        }
        return false;
    }

    public void ordenar() {
        String property = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap()
                .get("sortProperty");

        if (property != null) {
            if (columnaSorteada.equals(property)) {
                ascendiente = !ascendiente;
            } else {
                columnaSorteada = property;
                ascendiente = true;
            }
        }

        llenarSolicitudes();
    }

    public void ordenarAprobadas() {
        String property = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap()
                .get("sortProperty");

        if (property != null) {
            if (columnaSorteada.equals(property)) {
                ascendiente = !ascendiente;
            } else {
                columnaSorteada = property;
                ascendiente = true;
            }
        }

        llenarSolicitudesAprobar();
    }

    private SolicitudDto getDtoSolicitudesAprobar() {
        Usuario usuario = sesionBean.getUsuario();
        List<EstadosSolicitudEnum> estados = new ArrayList<EstadosSolicitudEnum>();

        estados.add(EstadosSolicitudEnum.POR_APROBAR);

        SolicitudDto dto = new SolicitudDto();

        if (!rol.getIdGrupo().equals(GruposEnum.ADMINISTRADOR.getId())) {
            dto.setIdGerenciaAprobadora(usuario.getGerencia().getIdGerencia());
            dto.setEscalado(true);
        }
        dto.setEstados(estados);
        dto.setAscendiente(ascendiente);
        dto.setCampoSorteado(columnaSorteada);

        return dto;
    }

    //+++++++++++++++++++++++ GETTERS Y SETTERS +++++++++++++++++++++++++++++++++++
//    public List<Solicitud> getSolicitudes() {
//        return solicitudes;
//    }
//
//    public void setSolicitudes(List<Solicitud> solicitudes) {
//        this.solicitudes = solicitudes;
//    }
    public SolicitudesDynamicDataModel getSolicitudes() {
        return solicitudes;
    }

    public void setSolicitudes(SolicitudesDynamicDataModel solicitudes) {
        this.solicitudes = solicitudes;
    }

    public SolicitudesDynamicDataModel getSolicitudesAprobar() {
        return solicitudesAprobar;
    }

    public void setSolicitudesAprobar(SolicitudesDynamicDataModel solicitudesAprobar) {
        this.solicitudesAprobar = solicitudesAprobar;
    }

    public String getGerenciaSeleccionado() {
        return gerenciaSeleccionado;
    }

    public void setGerenciaSeleccionado(String gerenciaSeleccionado) {
        this.gerenciaSeleccionado = gerenciaSeleccionado;
    }

    public UsuarioSessionBean getSesionBean() {
        return sesionBean;
    }

    public void setSesionBean(UsuarioSessionBean sesionBean) {
        this.sesionBean = sesionBean;
    }

//    public List<Solicitud> getSolicitudesAprobar() {
//        return solicitudesAprobar;
//    }
//
//    public void setSolicitudesAprobar(List<Solicitud> solicitudesAprobar) {
//        this.solicitudesAprobar = solicitudesAprobar;
//    }
    public boolean isIsAprobador() {
        return isAprobador;
    }

    public void setIsAprobador(boolean isAprobador) {
        this.isAprobador = isAprobador;
    }

    public boolean isIsAsignador() {
        return isAsignador;
    }

    public void setIsAsignador(boolean isAsignador) {
        this.isAsignador = isAsignador;
    }

    public boolean isIsEjecutor() {
        return isEjecutor;
    }

    public void setIsEjecutor(boolean isEjecutor) {
        this.isEjecutor = isEjecutor;
    }

    public int getFilas() {
        return filas;
    }

    public boolean isAscendiente() {
        return ascendiente;
    }

}
